home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / tsr / cint16 / cint16.asm next >
Encoding:
Assembly Source File  |  1987-08-05  |  14.5 KB  |  373 lines

  1.         TITLE   LC Interrupt trap routine
  2.         NAME    LCINT
  3.         INCLUDE DOS.MAC                 ; BE SURE TO INCLUDE THE CORRECT
  4.                                         ; DOS.MAC!!
  5.  
  6. ;****************************************************************************
  7. ;
  8. ; This is the heart of a C driven interrupt handler. This file was used to
  9. ; write a critical error handler that remained resident. (It replaced the
  10. ; "Abort, Retry, Ignore" prompt with a window.) This file can be adapted to
  11. ; any interrupt and any C routine with a little work. THIS HAS BEEN USED ONLY
  12. ; IN THE S MODEL.
  13. ;
  14. ; REVISION HISTORY:
  15. ;
  16. ;       7/19/87         Thomas A. Lundin
  17. ;                       Graphics Unlimited Inc.
  18. ;                       3000 Second St. No.
  19. ;                       Minneapolis, MN 55411
  20. ;                       (612) 588-7571
  21. ;
  22. ; Implemented DOS stack save/restore for a more stable exit from & reentry to
  23. ; the original DOS environment which called us.
  24. ;
  25. ;       8/4/87          TAL again
  26. ;
  27. ; Now try the keyboard interrupt vector. Also added some routines (but did
  28. ; not activate them here) which save/restore the caller's PSP and DTA. Why?
  29. ; I had some silly notion that it might help my TSR program from bombing when
  30. ; issuing DOS calls when other DOS calls are in process. Hah! I should have
  31. ; known better. But I left them in, in case you are interested. The kludge I
  32. ; ended up with checks the DOS "Critical Section Flag" and disables any calls
  33. ; to DOS when other calls are in process. That section of code has also been
  34. ; commented out. Also made some changes to my 7/19/87 modifications.
  35. ;****************************************************************************
  36.  
  37. DOS_INT         EQU 16H                 ; int to be replaced (keyboard)
  38.  
  39. WRITE_INT       EQU 25H                 ; DOS write int vector
  40. READ_INT        EQU 35H                 ; DOS read int vector
  41. ;******************************************************************************
  42. HOTKEY          EQU 1300H               ; ALT-R here - can be anything you want
  43. ;******************************************************************************
  44. STAK_LEN        EQU 800H                ; size of stack area to save ;;;;;;;;;;
  45.  
  46.  
  47. XREG    STRUC
  48. REG_AX  DW      ?                       ; general purpose registers
  49. REG_BX  DW      ?                       
  50. REG_CX  DW      ?
  51. REG_DX  DW      ?
  52. REG_SI  DW      ?
  53. REG_DI  DW      ?
  54. XREG    ENDS
  55.  
  56. SREGS   STRUC
  57. REG_ES  DW      ?                       ; segment registers
  58. REG_CS  DW      ?
  59. REG_SS  DW      ?
  60. REG_DS  DW      ?
  61. SREGS   ENDS
  62.  
  63.         DSEG
  64.  
  65.         INT_REGS        XREG    <>              ; saved regs. at int time
  66.         INT_SEGREGS     SREGS   <>              ; saved seg. regs.
  67.         EXTRN           _TOP:WORD               ; declared by C.ASM -- points
  68.                                                 ; to top of stack
  69.         EXTRN           _STACK:WORD             ; size of stack
  70.         PUBLIC          _INDOS                  ; if _INDOS is non-zero...
  71. _INDOS          DW      0                       ; ...then don't interrupt DOS
  72.         ENDDS
  73.  
  74.         EXTRN   INTTIME:NEAR                    ; your int routine goes here!
  75.  
  76.         PSEG
  77. ;;
  78. ; interrupt time data storage
  79. ;;
  80. C_ENVIRONMENT_DS DW ?                   ; filled by int init, used...
  81. C_ENVIRONMENT_ES DW ?                   ; ...to recreate C environment
  82. C_ENVIRONMENT_SS DW ?
  83. C_ENVIRONMENT_SP DW ?
  84.  
  85. INT_TIME_ES     DW ?
  86. INT_TIME_DS     DW ?                    ; temp save of DS at int time
  87. INT_TIME_SI     DW ?                    ; temp save of SI at int time
  88.  
  89. INT_TIME_BP     DW ?                    ; added to account for no BP or SP...
  90. INT_TIME_SP     DW ?                    ; ...in above structures
  91.  
  92. RETURN_VALUE    DW ?                    ; return value from C service routine
  93.  
  94. DOS_SERVICE     DD      ?               ; address of DOS Service routine
  95. INT_TWOONE      DD ?                    ; old INT 21 vector
  96.  
  97. INT_IN_PROGRESS DB 0                    ; interrupt in progress flag
  98.  
  99. CALSTK  DB      STAK_LEN DUP(?) ;caller's stack save area ;;;;;;;;;;;;;;;;;;;;;
  100. STKSEG  DW      ?               ;which stack segment ;;;;;;;;;;;;;;;;;;;;;;;;;;
  101. FLAGS   DW      ?               ;caller's flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  102.  
  103. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  104. ;DOSDTA  DD      ?               ;caller's DTA
  105. ;C_DTA   DD      ?               ;C's DTA
  106. ;DOSPSP  DW      ?               ;caller's PSP
  107. ;C_PSP   DW      ?               ;C's PSP
  108. ;;**************************************************************************
  109. ; name          LC_SERVICE_INT
  110. ;
  111. ; description   Entered at (software) interrupt time, this routine
  112. ;               restores the C enviroment and processes the interrupt
  113. ;               trapping all references to the quad file
  114. ;;
  115.  
  116.         IF      LPROG
  117. LC_SERVICE_INT PROC     FAR
  118.         ELSE
  119. LC_SERVICE_INT PROC     NEAR
  120.         ENDIF
  121.  
  122. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  123. ; This section of code can be commented out if you don't wish to trap the
  124. ; keyboard interrupt. Remember, then, to change the DOS_INT EQUate to whatever
  125. ; interrupt it is you DO want to trap.
  126.  
  127.         CMP     CS:INT_IN_PROGRESS,1    ; already in this interrupt?
  128.         JNE     FIRST_TIME              ; no, check the key
  129. EXIT16:
  130.         JMP     DWORD PTR CS:DOS_SERVICE ; else forget it
  131.  
  132. FIRST_TIME:
  133.         CMP     AH,0                    ; is this character request
  134.         JNE     EXIT16                  ; no, exit immediately
  135.         PUSHF
  136.         CALL    DWORD PTR CS:DOS_SERVICE ; get the next character from buffer
  137.         CMP     AX,HOTKEY               ; is it the hot key?
  138.         JE      HOT_HIT                 ; yes, dive into the interrupt
  139.         IRET                            ; no, send the char back to caller
  140. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  141. HOT_HIT:
  142.         MOV     CS:INT_IN_PROGRESS,1    ; set int in progress flag
  143.  
  144.         MOV     CS:INT_TIME_ES,ES       ; save ES so it can be overwritten
  145.         MOV     CS:INT_TIME_DS,DS       ; save DS so it can be overwritten
  146.         MOV     CS:INT_TIME_SI,SI       ; save SI so it can be overwritten
  147.         MOV     CS:INT_TIME_BP,BP       ; save BP as structs do not have it
  148.         MOV     CS:INT_TIME_SP,SP       ; save SP as structs do not have it
  149.         MOV     DS,CS:C_ENVIRONMENT_DS  ; set up C enviroment
  150.         MOV     SI,OFFSET INT_REGS      ; point to input regs struct
  151.  
  152.         MOV     DS:[SI].REG_AX,AX       ; save general purpose regs
  153.         MOV     DS:[SI].REG_BX,BX
  154.         MOV     DS:[SI].REG_CX,CX
  155.         MOV     DS:[SI].REG_DX,DX
  156.         MOV     DS:[SI].REG_DI,DI
  157.         MOV     AX,CS:INT_TIME_SI       ; SI has been overwritten
  158.         MOV     DS:[SI].REG_SI,AX
  159.  
  160.         MOV     SI,OFFSET INT_SEGREGS   ; point to input segment regs struct
  161.  
  162.         MOV     AX,CS:INT_TIME_ES       ; ES has been overwritten
  163.         MOV     DS:[SI].REG_ES,AX
  164.         MOV     DS:[SI].REG_SS,SS
  165.         MOV     AX,CS:INT_TIME_DS       ; DS has been overwritten
  166.         MOV     DS:[SI].REG_DS,AX
  167. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  168.         PUSHF
  169.         POP     AX
  170.         MOV     CS:FLAGS,AX             ;save caller's flags
  171.         MOV     SI,SS
  172.         MOV     WORD PTR CS:STKSEG,SI   ;save caller's stack segment
  173.         PUSH    DS
  174.         CLI
  175.         MOV     AX,CS                   ;save area address
  176.         MOV     ES,AX
  177.         MOV     AX,WORD PTR CS:STKSEG   ;caller's stack address
  178.         MOV     DS,AX
  179.         MOV     SI,0                    ;stack offset
  180.         MOV     DI,OFFSET CS:CALSTK
  181.         MOV     CX,STAK_LEN             ;length to save
  182.         CLD
  183.         REP     MOVSB                   ;save caller's stack
  184.         STI
  185. ;........................................
  186. ;       MOV     AX,2F00H                ;get caller's DTA
  187. ;       INT     21H
  188. ;       MOV     WORD PTR CS:DOSDTA+2,ES ;save it
  189. ;       MOV     WORD PTR CS:DOSDTA,BX
  190. ;
  191. ;       MOV     AX,5100H                ;get caller's PSP
  192. ;       INT     21H
  193. ;       MOV     CS:DOSPSP,BX            ;save it
  194. ;
  195. ;       MOV     AX,1A00H                ;set C's DTA
  196. ;       MOV     DX,WORD PTR CS:C_DTA
  197. ;       MOV     DS,WORD PTR CS:C_DTA+2
  198. ;       INT     21H
  199. ;
  200. ;       MOV     BX,CS:C_PSP
  201. ;       MOV     AX,5000H                ;set C's PSP
  202. ;       INT     21H
  203. ;........................................
  204.         POP     DS
  205. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  206.         MOV     ES,CS:C_ENVIRONMENT_ES  ; complete C environment
  207.         MOV     SS,CS:C_ENVIRONMENT_SS
  208.         MOV     SP,CS:C_ENVIRONMENT_SP
  209. ;----------------------------------------
  210. ;       PUSH    ES                      ;
  211. ;       PUSH    BX                      ;
  212. ;       PUSH    AX                      ;
  213. ;       MOV     AX,3400H                ; the "Critical Section Flag"
  214. ;       INT     21H                     ; determines DOS interruptability
  215. ;       MOV     AL,BYTE PTR ES:[BX]     ;
  216. ;       MOV     BYTE PTR CS:_INDOS,AL   ; save it for INTTIME
  217. ;       POP     AX                      ;
  218. ;       POP     BX                      ;
  219. ;       POP     ES                      ;
  220. ;----------------------------------------
  221.  
  222.         CALL    INTTIME                 ; call the C routine
  223.  
  224.         MOV     CS:RETURN_VALUE,AX      ; save return value
  225.         XOR     AX,AX
  226. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  227.         PUSH    DS
  228. ;........................................
  229. ;       MOV     AX,1A00H                ;reinstate DOS DTA
  230. ;       MOV     DX,WORD PTR CS:DOSDTA
  231. ;       MOV     DS,WORD PTR CS:DOSDTA+2
  232. ;       INT     21H
  233. ;
  234. ;       MOV     BX,CS:DOSPSP
  235. ;       MOV     AX,5000H                ;and DOS PSP
  236. ;       INT     21H
  237. ;........................................
  238.         CLI
  239.         MOV     AX,WORD PTR CS:STKSEG   ;restore caller's stack area 
  240.         MOV     ES,AX
  241.         MOV     DI,0                    ;restore data areas
  242.         MOV     AX,CS
  243.         MOV     DS,AX
  244.         MOV     SI,OFFSET CS:CALSTK
  245.         MOV     CX,STAK_LEN             ;length to restore
  246.         CLD
  247.         REP     MOVSB                   ;copy stack data
  248.         STI
  249.         POP     DS
  250.  
  251.         MOV     AX,CS:FLAGS
  252.         PUSH    AX
  253.         POPF                            ;restore caller's flags
  254. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  255.         MOV     SI,OFFSET INT_REGS      ; point to input regs struct
  256.  
  257.         MOV     AX,DS:[SI].REG_SI       ; SI needs to be saved while used
  258.         MOV     CS:INT_TIME_SI,AX
  259.  
  260.         MOV     AX,DS:[SI].REG_AX       ; restore general purpose regs
  261.         MOV     BX,DS:[SI].REG_BX
  262.         MOV     CX,DS:[SI].REG_CX
  263.         MOV     DX,DS:[SI].REG_DX
  264.         MOV     DI,DS:[SI].REG_DI
  265.  
  266.         MOV     SI,OFFSET INT_SEGREGS   ; point to input segment regs struct
  267.  
  268.         MOV     ES,DS:[SI].REG_DS       ; DS needs to be saved while used
  269.         MOV     CS:INT_TIME_DS,ES
  270.  
  271.         MOV     ES,DS:[SI].REG_ES
  272.         MOV     SS,DS:[SI].REG_SS
  273.  
  274.         MOV     SI,CS:INT_TIME_SI       ; restore pointing registers
  275.         MOV     DS,CS:INT_TIME_DS
  276.  
  277.         MOV     BP,CS:INT_TIME_BP       ; special BP restore
  278.         MOV     SP,CS:INT_TIME_SP       ; special SP restore
  279.  
  280.         MOV     CS:INT_IN_PROGRESS,0    ; clear int in progress flag
  281.         MOV     AX,CS:RETURN_VALUE      ; move the return value
  282.         OR      AX,AX ;;;;;;;;;;;;;;;;;;; return value ?
  283.         JNZ     DONE  ;;;;;;;;;;;;;;;;;;; yes, pass it through as keystroke
  284.         JMP     CS:LC_SERVICE_INT ;;;;;;; no, fetch the next keystroke
  285. DONE:
  286.         IRET                            ; return from interrupt
  287.  
  288. LC_SERVICE_INT  ENDP
  289.  
  290. ;****************************************************************************
  291. ; description   set up the LC interrupt routines
  292. ;
  293. ;               INT_INIT -- Hooks into the specified int.
  294. ;               INT_TERM -- Unhooks (restores) the specified int.
  295. ;
  296. ; NOTE: INT_INIT must be called be int processing can begin...it saves the 
  297. ;       current C environment for use at interrupt time.
  298. ;;
  299.  
  300.                 PUBLIC  INT_INIT
  301.                 IF      LPROG
  302. INT_INIT        PROC    FAR
  303.                 ELSE
  304. INT_INIT        PROC    NEAR
  305.                 ENDIF
  306.  
  307.         PUSH    DS                      ; save changed seg regs
  308.         PUSH    ES
  309.  
  310.         MOV     CS:C_ENVIRONMENT_DS,DS  ; save C environment for int time
  311.         MOV     CS:C_ENVIRONMENT_ES,ES
  312.         MOV     CS:C_ENVIRONMENT_SS,SS
  313.  
  314.         MOV     AX,_TOP                 ; determine int time SP
  315.         MOV     BX,_STACK               ; get size of STACK ;;;;;;;;;;;;;;;;;;;
  316.         ROR     BX,1                    ; div by 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  317.         SUB     AX,BX                   ; split it in two ;;;;;;;;;;;;;;;;;;;;;
  318.         MOV     CS:C_ENVIRONMENT_SP,AX
  319.  
  320.         MOV     AH,READ_INT             ; read int vector function
  321.         MOV     AL,DOS_INT              ; specify DOS service vector
  322.         INT     21H
  323.  
  324.         MOV     WORD PTR CS:DOS_SERVICE+2,ES    ; save current vector
  325.         MOV     WORD PTR CS:DOS_SERVICE,BX
  326.  
  327.         LEA     DX,LC_SERVICE_INT       ; Use DOS to set new int address
  328.         PUSH    CS
  329.         POP     DS
  330.         MOV     AH,WRITE_INT
  331.         MOV     AL,DOS_INT
  332.         INT     21H
  333.  
  334. ;::::::::::::::::::::::::::::::::::::::::
  335. ;       MOV     AX,2F00H                ;get C's DTA
  336. ;       INT     21H
  337. ;       MOV     WORD PTR CS:C_DTA+2,ES  ;save it
  338. ;       MOV     WORD PTR CS:C_DTA,BX
  339. ;
  340. ;       MOV     AX,5100H                ;get C's PSP
  341. ;       INT     21H
  342. ;       MOV     CS:C_PSP,BX             ;save it
  343. ;::::::::::::::::::::::::::::::::::::::::
  344.         POP     ES                      ; restore changed seg regs
  345.         POP     DS
  346.         RET
  347.  
  348. INT_INIT        ENDP
  349.  
  350. ;********************* INT_TERM -- kill ints. *******************************
  351.  
  352.                 PUBLIC INT_TERM
  353.                 IF      LPROG
  354. INT_TERM        PROC    FAR
  355.                 ELSE
  356. INT_TERM        PROC    NEAR
  357.                 ENDIF
  358.  
  359.         PUSH    DS                      ; DS gets changed
  360.  
  361.         MOV     DS,WORD PTR CS:DOS_SERVICE+2    ; Restore previous DOS service vector
  362.         MOV     DX,WORD PTR CS:DOS_SERVICE
  363.         MOV     AH,WRITE_INT
  364.         MOV     AL,DOS_INT
  365.         INT     21H
  366.  
  367.         POP     DS                      ; restore DS
  368.         RET
  369. INT_TERM        ENDP
  370.  
  371.         ENDPS
  372.         END
  373.